package com.tanhua.locationmanager.interceptors;

import com.alibaba.fastjson.JSON;
import com.tanhua.domain.db.Admin;
import com.tanhua.locationmanager.constants.Constants;
import com.tanhua.locationmanager.exceptions.TanhuaException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Component
public class TokenInterceptor implements HandlerInterceptor {

    private final StringRedisTemplate redisTemplate;

    public TokenInterceptor(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//       进入到方法之前拦截
//        从token中获取 用户user  放到ThreadLocal中
        String token = request.getHeader("Authorization");
		//        把页面上带过来的token中的“Bearer ”去掉
        if(token==null){
            response.setStatus(HttpStatus.FORBIDDEN.value());
            return false;
        }
        Admin admin = findAdminByToken(token);
		admin.setToken(token);
        AdminHolder.setAdmin(admin);

        return true;// 代表拦截  true:放行
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//        方法执行完成后，把ThreadLocal中的数据删除，不然数据多了会造成内存溢出
        AdminHolder.removeAdmin();
    }

    private Admin findAdminByToken(String token) {
        String adminStr = redisTemplate.boundValueOps(Constants.CACHE_KEY_TOKEN_PREFIX+token).get();
        if(adminStr == null) {
            throw new TanhuaException(500,"登录超时");
        }
        redisTemplate.boundValueOps(Constants.CACHE_KEY_TOKEN_PREFIX+token).set(adminStr,2, TimeUnit.HOURS);//续期
        return JSON.parseObject(adminStr,Admin.class);
    }
}
